package com.sxf.djiuav;

import androidx.lifecycle.MutableLiveData;
import dji.sdk.keyvalue.key.FlightControllerKey;
import dji.sdk.keyvalue.key.KeyTools;
import dji.sdk.keyvalue.value.common.LocationCoordinate2D;
import dji.sdk.keyvalue.value.common.LocationCoordinate3D;
import dji.v5.common.callback.CommonCallbacks;
import dji.v5.common.error.IDJIError;
import dji.v5.manager.KeyManager;
import dji.v5.manager.aircraft.flysafe.FlySafeDatabaseComponent;
import dji.v5.manager.aircraft.flysafe.FlySafeDatabaseListener;
import dji.v5.manager.aircraft.flysafe.FlySafeDatabaseState;
import dji.v5.manager.aircraft.flysafe.FlySafeDatabaseUpgradeMode;
import dji.v5.manager.aircraft.flysafe.FlySafeNotificationListener;
import dji.v5.manager.aircraft.flysafe.FlyZoneManager;
import dji.v5.manager.aircraft.flysafe.info.FlySafeDatabaseInfo;
import dji.v5.manager.aircraft.flysafe.info.FlySafeReturnToHomeInformation;
import dji.v5.manager.aircraft.flysafe.info.FlySafeSeriousWarningInformation;
import dji.v5.manager.aircraft.flysafe.info.FlySafeTipInformation;
import dji.v5.manager.aircraft.flysafe.info.FlySafeWarningInformation;
import dji.v5.manager.aircraft.flysafe.info.FlyZoneInformation;
import dji.v5.manager.aircraft.flysafe.info.FlyZoneLicenseInfo;
import dji.v5.utils.common.ContextUtil;
import dji.v5.utils.common.FileUtils;

import java.io.File;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;

/**
 * 飞行安全管理类
 * 对应 Kotlin 版本的 FlySafeVM.kt
 */
public class FlySafe {

    // LiveData 用于UI观察
    public MutableLiveData<FlySafeWarningInformation> flySafeWarningInformation = new MutableLiveData<>();
    public MutableLiveData<FlySafeSeriousWarningInformation> flySafeSeriousWarningInformation = new MutableLiveData<>();
    public MutableLiveData<FlySafeReturnToHomeInformation> flySafeReturnToHomeInformation = new MutableLiveData<>();
    public MutableLiveData<FlySafeTipInformation> flySafeTipInformation = new MutableLiveData<>();
    public MutableLiveData<List<FlyZoneInformation>> flyZoneInformation = new MutableLiveData<>();
    public MutableLiveData<List<FlyZoneLicenseInfo>> serverFlyZoneLicenseInfo = new MutableLiveData<>();
    public MutableLiveData<List<FlyZoneLicenseInfo>> aircraftFlyZoneLicenseInfo = new MutableLiveData<>();
    public MutableLiveData<ImportAndSyncState> importAndSyncState = new MutableLiveData<>();
    public MutableLiveData<DataBaseInfo> dataBaseInfo = new MutableLiveData<>();
    public MutableLiveData<FlySafeDatabaseState> dataUpgradeState = new MutableLiveData<>();

    // 用于Toast结果回调，需要根据实际情况实现
    public MutableLiveData<Object> toastResult = new MutableLiveData<>();

    private final String availableTestFlySafeDynamicDatabaseName = "de.geojson";
    private final String unAvailableTestFlySafeDynamicDatabaseName = "France.json";

    // 监听器
    private FlySafeNotificationListener flySafeNotificationListener;
    private FlySafeDatabaseListener flySafeDatabaseListener;

    /**
     * 初始化监听器
     */
    public void initListener() {
        addFlySafeNotificationListener();
        addFlySafeDatabaseListener();
    }

    /**
     * 清理资源
     */
    public void onCleared() {
        KeyManager.getInstance().cancelListen(this);
        removeFlySafeNotificationListener();
        removeFlySafeDatabaseListener();
    }

    /**
     * 添加飞行安全通知监听
     */
    private void addFlySafeNotificationListener() {
        flySafeNotificationListener = new FlySafeNotificationListener() {
            @Override
            public void onWarningNotificationUpdate(FlySafeWarningInformation info) {
                flySafeWarningInformation.postValue(info);
            }

            @Override
            public void onSeriousWarningNotificationUpdate(FlySafeSeriousWarningInformation info) {
                flySafeSeriousWarningInformation.postValue(info);
            }

            @Override
            public void onReturnToHomeNotificationUpdate(FlySafeReturnToHomeInformation info) {
                flySafeReturnToHomeInformation.postValue(info);
            }

            @Override
            public void onTipNotificationUpdate(FlySafeTipInformation info) {
                flySafeTipInformation.postValue(info);
            }

            @Override
            public void onSurroundingFlyZonesUpdate(List<FlyZoneInformation> infos) {
                flyZoneInformation.postValue(infos);
            }
        };

        FlyZoneManager.getInstance().addFlySafeNotificationListener(flySafeNotificationListener);
    }

    /**
     * 移除飞行安全通知监听
     */
    private void removeFlySafeNotificationListener() {
        if (flySafeNotificationListener != null) {
            FlyZoneManager.getInstance().removeFlySafeNotificationListener(flySafeNotificationListener);
        }
    }

    /**
     * 移除全部飞行安全通知监听
     */
    public void clearAllFlySafeNotificationListener() {
        FlyZoneManager.getInstance().clearAllFlySafeNotificationListener();
    }

    /**
     * 添加飞行安全数据库监听
     */
    private void addFlySafeDatabaseListener() {
        flySafeDatabaseListener = new FlySafeDatabaseListener() {
            @Override
            public void onFlySafeDatabaseInfoUpdate(FlySafeDatabaseInfo flySafeDatabaseInfo) {
                dataBaseInfo.postValue(new DataBaseInfo(
                        flySafeDatabaseInfo.getDatabaseName(),
                        formatCEDBTime(flySafeDatabaseInfo.getDatabaseTimeStamp() * 1000),
                        byte2AdaptiveUnitStrDefault(flySafeDatabaseInfo.getDatabaseSize()),
                        flySafeDatabaseInfo.getComponent(),
                        flySafeDatabaseInfo.getFlySafeDatabaseUpgradeMode()
                ));
            }

            @Override
            public void onFlySafeDatabaseStateUpdate(FlySafeDatabaseState flySafeDatabaseState) {
                dataUpgradeState.postValue(flySafeDatabaseState);
            }
        };

        FlyZoneManager.getInstance().addFlySafeDatabaseListener(flySafeDatabaseListener);
    }

    /**
     * 移除飞行安全数据库监听
     */
    private void removeFlySafeDatabaseListener() {
        FlyZoneManager.getInstance().clearAllFlySafeDatabaseListener();
    }

    /**
     * 获取飞行器位置
     */
    public LocationCoordinate3D getAircraftLocation() {
        return KeyManager.getInstance().getValue(
                KeyTools.createKey(FlightControllerKey.KeyAircraftLocation3D),
                new LocationCoordinate3D(0.0, 0.0, 0.0)
        );
    }

    /**
     * 获取飞行器附近限飞区
     */
    public void getFlyZonesInSurroundingArea(LocationCoordinate2D location) {
        FlyZoneManager.getInstance().getFlyZonesInSurroundingArea(location,
                new CommonCallbacks.CompletionCallbackWithParam<List<FlyZoneInformation>>() {
                    @Override
                    public void onSuccess(List<FlyZoneInformation> infos) {
                        postToastResult(true, null);
                        flyZoneInformation.postValue(infos != null ? infos : new ArrayList<>());
                    }

                    @Override
                    public void onFailure(IDJIError error) {
                        postToastResult(false, error.toString());
                    }
                });
    }

    /**
     * 从服务器获取证书
     * 需要预先登陆账号 loginDJIUserAccount()
     */
    public void downloadFlyZoneLicensesFromServer() {
        FlyZoneManager.getInstance().downloadFlyZoneLicensesFromServer(
                new CommonCallbacks.CompletionCallbackWithParam<List<FlyZoneLicenseInfo>>() {
                    @Override
                    public void onSuccess(List<FlyZoneLicenseInfo> infos) {
                        postToastResult(true, null);
                        serverFlyZoneLicenseInfo.postValue(infos != null ? infos : new ArrayList<>());
                    }

                    @Override
                    public void onFailure(IDJIError error) {
                        postToastResult(false, error.toString());
                    }
                });
    }

    /**
     * 将证书导入飞行器
     * 需要保证证书的SN与飞行器飞控SN一致
     */
    public void pushFlyZoneLicensesToAircraft() {
        FlyZoneManager.getInstance().pushFlyZoneLicensesToAircraft(
                new CommonCallbacks.CompletionCallback() {
                    @Override
                    public void onSuccess() {
                        pullFlyZoneLicensesFromAircraft();
                        postToastResult(true, null);
                    }

                    @Override
                    public void onFailure(IDJIError error) {
                        postToastResult(false, error.toString());
                    }
                });
    }

    /**
     * 获取飞行器中已有的证书列表
     * 从飞行器上导出的证书会更完整
     */
    public void pullFlyZoneLicensesFromAircraft() {
        FlyZoneManager.getInstance().pullFlyZoneLicensesFromAircraft(
                new CommonCallbacks.CompletionCallbackWithParam<List<FlyZoneLicenseInfo>>() {
                    @Override
                    public void onSuccess(List<FlyZoneLicenseInfo> infos) {
                        postToastResult(true, null);
                        aircraftFlyZoneLicenseInfo.postValue(infos != null ? infos : new ArrayList<>());
                    }

                    @Override
                    public void onFailure(IDJIError error) {
                        postToastResult(false, error.toString());
                    }
                });
    }

    /**
     * 从飞行器删除证书
     */
    public void deleteFlyZoneLicensesFromAircraft() {
        FlyZoneManager.getInstance().deleteFlyZoneLicensesFromAircraft(
                new CommonCallbacks.CompletionCallback() {
                    @Override
                    public void onSuccess() {
                        postToastResult(true, null);
                    }

                    @Override
                    public void onFailure(IDJIError error) {
                        postToastResult(false, error.toString());
                    }
                });
    }

    /**
     * 使能/关闭证书
     */
    public void setFlyZoneLicensesEnabled(FlyZoneLicenseInfo info, boolean isEnable) {
        FlyZoneManager.getInstance().setFlyZoneLicensesEnabled(info, isEnable,
                new CommonCallbacks.CompletionCallback() {
                    @Override
                    public void onSuccess() {
                        pullFlyZoneLicensesFromAircraft();
                        postToastResult(true, null);
                    }

                    @Override
                    public void onFailure(IDJIError error) {
                        postToastResult(false, error.toString());
                    }
                });
    }

    /**
     * 解除授权区
     * 授权区ID可通过getFlyZonesInSurroundingArea()中的FlyZoneInformation获得
     */
    public void unlockAuthorizationFlyZone(int flyZoneID) {
        FlyZoneManager.getInstance().unlockAuthorizationFlyZone(flyZoneID,
                new CommonCallbacks.CompletionCallback() {
                    @Override
                    public void onSuccess() {
                        postToastResult(true, null);
                    }

                    @Override
                    public void onFailure(IDJIError error) {
                        postToastResult(false, error.toString());
                    }
                });
    }

    /**
     * 加密警告区解禁
     */
    public void unlockAllEnhancedWarningFlyZone() {
        FlyZoneManager.getInstance().unlockAllEnhancedWarningFlyZone(
                new CommonCallbacks.CompletionCallback() {
                    @Override
                    public void onSuccess() {
                        postToastResult(true, null);
                    }

                    @Override
                    public void onFailure(IDJIError error) {
                        postToastResult(false, error.toString());
                    }
                });
    }

    /**
     * 导入动态数据库到MSDK并同步到飞行器
     */
    public void pushFlySafeDynamicDatabaseToAircraftAndApp(String fileName) {
        FlyZoneManager.getInstance().importFlySafeDynamicDatabaseToMSDK(fileName,
                new CommonCallbacks.CompletionCallbackWithProgress<Double>() {
                    @Override
                    public void onProgressUpdate(Double progress) {
                        importAndSyncState.postValue(new ImportAndSyncState(progress.intValue()));
                    }

                    @Override
                    public void onSuccess() {
                        importAndSyncState.postValue(new ImportAndSyncState(100));
                    }

                    @Override
                    public void onFailure(IDJIError error) {
                        importAndSyncState.postValue(new ImportAndSyncState(-1, error));
                    }
                });
    }

    /**
     * 同步MSDK数据库到飞行器
     */
    public void syncFlySafeMSDKDatabaseToAircraft() {
        FlyZoneManager.getInstance().pushFlySafeDynamicDatabaseToAircraft(
                new CommonCallbacks.CompletionCallbackWithProgress<Double>() {
                    @Override
                    public void onProgressUpdate(Double progress) {
                        importAndSyncState.postValue(new ImportAndSyncState(Math.round(progress.floatValue())));
                    }

                    @Override
                    public void onSuccess() {
                        importAndSyncState.postValue(new ImportAndSyncState(100));
                    }

                    @Override
                    public void onFailure(IDJIError error) {
                        importAndSyncState.postValue(new ImportAndSyncState(-1, error));
                    }
                });
    }

    /**
     * 设置动态数据库升级模式
     */
    public void setFlySafeDynamicDatabaseUpgradeMode(FlySafeDatabaseUpgradeMode upgradeMode) {
        FlyZoneManager.getInstance().setFlySafeDynamicDatabaseUpgradeMode(upgradeMode,
                new CommonCallbacks.CompletionCallback() {
                    @Override
                    public void onSuccess() {
                        importAndSyncState.postValue(new ImportAndSyncState(100));
                    }

                    @Override
                    public void onFailure(IDJIError error) {
                        importAndSyncState.postValue(new ImportAndSyncState(-1, error));
                    }
                });
    }

    /**
     * 推送可用的测试动态数据库到App
     */
    public void pushAvailableTestFlySafeDynamicDatabaseToApp() {
        File file = new File(ContextUtil.getContext().getExternalFilesDir("/"), availableTestFlySafeDynamicDatabaseName);
        FileUtils.copyAssetsFileIfNeed(ContextUtil.getContext(), "flysafe/" + availableTestFlySafeDynamicDatabaseName, file);
        pushFlySafeDynamicDatabaseToAircraftAndApp(file.getPath());
    }

    /**
     * 推送不可用的测试动态数据库到App
     */
    public void pushUnAvailableTestFlySafeDynamicDatabaseToApp() {
        File file = new File(ContextUtil.getContext().getExternalFilesDir("/"), unAvailableTestFlySafeDynamicDatabaseName);
        FileUtils.copyAssetsFileIfNeed(ContextUtil.getContext(), "flysafe/" + unAvailableTestFlySafeDynamicDatabaseName, file);
        pushFlySafeDynamicDatabaseToAircraftAndApp(file.getPath());
    }

    /**
     * 格式化时间
     */
    private String formatCEDBTime(long timestamp) {
        SimpleDateFormat format = new SimpleDateFormat("yyyy/MM/dd");
        return format.format(timestamp);
    }

    /**
     * 字节大小转换为自适应单位字符串
     */
    private String byte2AdaptiveUnitStrDefault(long byteSize) {
        // 这里需要实现字节到自适应单位的转换逻辑
        // 暂时返回简单实现
        if (byteSize < 1024) {
            return byteSize + "B";
        } else if (byteSize < 1024 * 1024) {
            return String.format("%.1fKB", byteSize / 1024.0);
        } else {
            return String.format("%.1fMB", byteSize / (1024.0 * 1024.0));
        }
    }

    /**
     * 发送Toast结果
     */
    private void postToastResult(boolean success, String error) {
        // 这里需要根据你的Toast实现来调整
        // toastResult.postValue(new DJIToastResult(success ? "success" : "failed", error));
    }

    /**
     * 数据库信息类
     */
    public static class DataBaseInfo {
        public String dataBaseName;
        public String dataBaseTime;
        public String dataBaseSize;
        public FlySafeDatabaseComponent component;
        public FlySafeDatabaseUpgradeMode upgradeMode;

        public DataBaseInfo(String dataBaseName, String dataBaseTime, String dataBaseSize,
                            FlySafeDatabaseComponent component, FlySafeDatabaseUpgradeMode upgradeMode) {
            this.dataBaseName = dataBaseName;
            this.dataBaseTime = dataBaseTime;
            this.dataBaseSize = dataBaseSize;
            this.component = component;
            this.upgradeMode = upgradeMode;
        }
    }

    /**
     * 导入和同步状态类
     */
    public static class ImportAndSyncState {
        public int importAndSyncProgress;
        public IDJIError error;

        public ImportAndSyncState(int importAndSyncProgress) {
            this.importAndSyncProgress = importAndSyncProgress;
        }

        public ImportAndSyncState(int importAndSyncProgress, IDJIError error) {
            this.importAndSyncProgress = importAndSyncProgress;
            this.error = error;
        }
    }
}